// Package dao
// @Author zhongxc
// @Date 2024/7/26 15:26:00
// @Desc
package dao

import (
	"context"
	"errors"
	"fmt"
	"gorm.io/gorm"
	"math"
	"strconv"
	"strings"
	"vben-admin/pkg/dao/internal"
	"vben-admin/pkg/model"
	"vben-common/msdb"
	"vben-common/msdb/gorms"
)

type ButtonDao struct {
	conn    *gorms.GormConn
	columns *internal.ButtonColumns
}

func NewButtonDao(db *msdb.MsDB) *ButtonDao {
	return &ButtonDao{
		conn:    gorms.New(db.Conn),
		columns: internal.NewButtonColumns(),
	}
}

func (i *ButtonDao) getSession(ctx context.Context) *gorm.DB {
	return i.conn.Session(ctx)
}

// CreateButton
// @Description: 创建接口
// @receiver i
// @param ctx
// @param ButtonModel
// @return error
func (i *ButtonDao) CreateButton(ctx context.Context, buttonModel *model.ButtonModel) error {
	err := i.getSession(ctx).Omit(model.IgnoreUpdatedAt, model.IgnoreUpdatedBy).Create(buttonModel).Error
	return err
}

// UpdateButton
// @Description: 更新接口
// @receiver i
// @param ctx
// @param id
// @param data
// @return error
func (i *ButtonDao) UpdateButton(ctx context.Context, id int64, data map[string]interface{}) error {
	err := i.getSession(ctx).
		Model(&model.ButtonModel{}).
		Where(fmt.Sprintf("%s=?", i.columns.Id), id).
		Updates(data).
		Error
	return err
}

func (i *ButtonDao) DeleteButton(ctx context.Context, ids []int64) error {
	err := i.getSession(ctx).
		Where(fmt.Sprintf("%s in (?)", i.columns.Id), ids).
		Delete(&model.ButtonModel{}).
		Error
	return err
}

func (i *ButtonDao) GetButtonList(ctx context.Context, name, code string, page, limit int64) (map[string]interface{}, error) {
	// 总记录数统计
	var total int64
	var buttons []*model.ButtonModel
	db := i.getSession(ctx)
	{
		if strings.TrimSpace(name) != "" {
			db = db.Where(fmt.Sprintf("%s LIKE ?", i.columns.Name), "%"+name+"%")
		}
		if strings.TrimSpace(code) != "" {
			db = db.Where(fmt.Sprintf("%s LIKE ?", i.columns.Code), "%"+code+"%")
		}
		db.Find(&buttons).Count(&total).Limit(1)
	}

	if total == 0 {
		return map[string]interface{}{
			"page":       page,
			"totalPage":  int64(0),
			"totalCount": total,
			"pageSize":   limit,
			"data":       make([]*model.ButtonModel, 0),
		}, nil
	}

	// 计算总的分页数
	pageCount := math.Ceil(float64(total) / float64(limit))
	pageCountStr := strconv.FormatFloat(pageCount, 'f', 0, 64)
	pageCountInt, err := strconv.ParseInt(pageCountStr, 10, 64)
	if err != nil {
		return nil, err
	}

	// 偏移量
	offset := (page - 1) * limit

	db = i.getSession(ctx)
	{
		if strings.TrimSpace(name) != "" {
			db = db.Where(fmt.Sprintf("%s LIKE ?", i.columns.Name), "%"+name+"%")
		}
		if strings.TrimSpace(code) != "" {
			db = db.Where(fmt.Sprintf("%s LIKE ?", i.columns.Code), "%"+code+"%")
		}

	}
	err = db.Limit(int(limit)).Offset(int(offset)).Order("id DESC").Find(&buttons).Error

	return map[string]interface{}{
		"page":       page,
		"totalPage":  pageCountInt,
		"totalCount": total,
		"pageSize":   limit,
		"data":       buttons,
	}, nil
}

func (i *ButtonDao) GetButtonInfo(ctx context.Context, id int64) (*model.ButtonModel, error) {
	var ButtonModel *model.ButtonModel
	err := i.getSession(ctx).Where(fmt.Sprintf("%s=?", i.columns.Id), id).First(&ButtonModel).Error
	if err != nil {
		if errors.Is(err, gorm.ErrRecordNotFound) {
			return nil, nil
		}
		return nil, err
	}
	return ButtonModel, nil
}

func (i *ButtonDao) FindByNameOrUrl(ctx context.Context, name, code string) (*model.ButtonModel, error) {
	var ButtonModel *model.ButtonModel
	db := i.getSession(ctx)
	{
		if strings.TrimSpace(name) != "" {
			db = db.Where(fmt.Sprintf("%s=?", i.columns.Name), name)
		}
		if strings.TrimSpace(code) != "" {
			db = db.Where(fmt.Sprintf("%s=?", i.columns.Code), code)
		}
	}
	err := db.First(&ButtonModel).Error
	if err != nil {
		if errors.Is(err, gorm.ErrRecordNotFound) {
			return nil, nil
		}
		return nil, err
	}
	return ButtonModel, nil
}

func (i *ButtonDao) GetAll(ctx context.Context) ([]*model.ButtonModel, error) {
	var buttons []*model.ButtonModel
	err := i.getSession(ctx).Find(&buttons).Error
	return buttons, err
}
